package com.msb.mall.member.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.msb.common.dto.MemberLoginDTO;
import com.msb.common.dto.SocialUser;
import com.msb.common.exception.BizCodeEnume;
import com.msb.common.utils.HttpClientUtils;
import com.msb.common.utils.R;
import com.msb.mall.member.entity.MemberLevelEntity;
import com.msb.mall.member.exception.PhoneExsitException;
import com.msb.mall.member.exception.UsernameExsitException;
import com.msb.mall.member.service.MemberLevelService;
import com.msb.common.dto.MemberRegisterDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.msb.common.utils.PageUtils;
import com.msb.common.utils.Query;

import com.msb.mall.member.dao.MemberDao;
import com.msb.mall.member.entity.MemberEntity;
import com.msb.mall.member.service.MemberService;


@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {

    @Autowired
    private MemberLevelService memberLevelService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MemberEntity> page = this.page(
                new Query<MemberEntity>().getPage(params),
                new QueryWrapper<MemberEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 用户注册
     * @param vo
     */
    @Override
    public void register(MemberRegisterDTO vo) {

        MemberEntity memberEntity = new MemberEntity();
        memberEntity.setUsername(vo.getUserName());
        memberEntity.setMobile(vo.getPhone());
        // 新用户注册，会员等级为默认，需要绑定
        MemberLevelEntity memberLevel = memberLevelService.getOne(new QueryWrapper<MemberLevelEntity>().eq("default_status", 1));
        memberEntity.setLevelId(memberLevel.getId());
        // 新用户注册，不能有重复的账号和手机号
        checkUsernameExsit(vo);
        checkPhoneExsit(vo);
        // 密码需要加密处理额·
        String password = vo.getPassword();
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        String encode = encoder.encode(password);
        memberEntity.setPassword(encode);
        memberEntity.setNickname(vo.getUserName());
        this.save(memberEntity);
    }

    /**
     * 登录
     * @param dto
     */
    @Override
    public R login(MemberLoginDTO dto) {
        MemberEntity one = this.getOne(new QueryWrapper<MemberEntity>()
                .eq("username", dto.getUsername())
                .or()
                .eq("mobile", dto.getUsername())
                .or()
                .eq("email", dto.getUsername())
        );
        if (one != null){
            // 存在该用户，完成密码校验
            BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
            boolean matches = encoder.matches(dto.getPassword(), one.getPassword());
            if (matches){
                return R.ok().put("memberEntity",one);
            }else {
                return R.error(BizCodeEnume.LOGIN_CHECK_EXCEPTION.getCode(), BizCodeEnume.LOGIN_CHECK_EXCEPTION.getMsg());
            }
        }
        // 不存在该用户
        return R.error(BizCodeEnume.USER_NOEXSIT_EXCEPTION.getCode(), BizCodeEnume.USER_NOEXSIT_EXCEPTION.getMsg());
    }

    /**
     * 社交平台登录-保存/更新
     * @param dto 社交用户token令牌等信息
     * @return
     */
    @Override
    public R login(SocialUser dto) {
        String uid = dto.getUid();
        MemberEntity member = this.getOne(new QueryWrapper<MemberEntity>().eq("uid", uid));
        if (null != member){
            // 存在该用户,更新token等信息
            MemberEntity memberEntity = new MemberEntity();
            memberEntity.setUid(dto.getUid());
            memberEntity.setAccessToken(dto.getAccessToken());
            memberEntity.setExpiresIn(dto.getExpiresIn());
            this.update(memberEntity,new UpdateWrapper<MemberEntity>().eq("uid",uid));
            // 返回的信息，同步保存token和过期时间
            member.setAccessToken(dto.getAccessToken());
            member.setExpiresIn(dto.getExpiresIn());
            return R.ok().put("memberEntity",member);
        }
        // 不存在该用户，新增
        MemberEntity memberEntity = new MemberEntity();
        HashMap<String, String> map = new HashMap<>();
        map.put("access_token",dto.getAccessToken());
        map.put("uid",dto.getUid());
        String json = HttpClientUtils.doGet("https://api.weibo.com/2/users/show.json", map);
        JSONObject jsonObject = JSON.parseObject(json);
        memberEntity.setNickname(jsonObject.getString("screen_name"));
        memberEntity.setUid(dto.getUid());
        memberEntity.setAccessToken(dto.getAccessToken());
        memberEntity.setExpiresIn(dto.getExpiresIn());
        String gender = jsonObject.getString("gender");
        if (!"n".equals(gender)){
            memberEntity.setGender("m".equals(gender)?1:0);
        }
        this.save(memberEntity);
        return R.ok().put("memberEntity",memberEntity);
    }

    /**
     * 校验手机已注册
     * @param vo
     */
    private void checkPhoneExsit(MemberRegisterDTO vo) {
        int phone = this.count(new QueryWrapper<MemberEntity>().eq("mobile", vo.getPhone()));
        if (phone>0){
            throw new PhoneExsitException();
        }
    }

    /**
     * 校验用户名已存在
     * @param vo
     */
    private void checkUsernameExsit(MemberRegisterDTO vo) {
        int username = this.count(new QueryWrapper<MemberEntity>().eq("username", vo.getUserName()));
        if (username>0){
            throw new UsernameExsitException();
        }
    }

}